/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Headquarters.viewPerspective;

import anotherFrameWork.matrixPoints;
import anotherFrameWork.point;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Polygon;
import java.awt.Stroke;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import thePieces.theSpritePieces;
import thePieces.theSpritePieces.colorOfPiexes;
import thePieces.theSpritePieces.kindOfPieces;

/**
 *
 * @author Windows7
 */
public abstract class perspective extends JPanel implements 
                                             PropertyChangeListener,
                                             MouseListener,
                                             MouseMotionListener{
     
    volatile theSpritePieces[][] View;
    
    protected matrixPoints mapPoint;
    
    protected Graphics2D bufferGraphic;
    
    protected Image buffer,backBuffer;
    
    private int w;
    
    private int h;
    
    volatile int xActive;
    
    volatile int yActive;
    
    private int xLocation;
    
    private int yLocation;
    
    protected colorOfPiexes side;
    
    protected Thread currentThread;
    
    private boolean notMove;
    
    public perspective(int w, int h)
    {
        mapPoint = new matrixPoints(new point(52,52),8,8, (float) 37);
        this.w = w;
        this.h = h;
        
        this.backBuffer = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = (Graphics2D) backBuffer.getGraphics();
        g.dispose();
        g = null;
        
        this.buffer = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
        this.bufferGraphic = (Graphics2D) this.buffer.getGraphics();
        
        //this.xActive = 4;
        //this.yActive = 4;
        
        this.xLocation = 4;
        this.yLocation = 4;
        //this.active = new point(this.mapPoint.getFromXY(4, 4).getX(),this.mapPoint.getFromXY(4, 4).getY());
        
        //float thickness = 2;
        this.bufferGraphic.setColor(Color.RED);
        this.bufferGraphic.setStroke(new BasicStroke(2));   
        
        this.notMove = true;
        //this.currentThread = new Thread(new animationTask());
        //this.currentThread.start();
        
        //this.bufferGraphic.setStroke(oldStroke);
        //point getPoint = this.mapPoint.getFromXY(this.yLocation, this.xLocation);
        
        this.setBounds(0, 0, w, h);
        
        this.addMouseListener(this);
        this.addMouseMotionListener(this);
        
        this.setOpaque(false);
    }
    

    
    @Override
    public void propertyChange(PropertyChangeEvent pce) 
    {
       Object a = pce.getSource();
       point i = (point) pce.getOldValue();
       System.out.printf(pce.getPropertyName()+" ,x: "+i.getX()+", y: "+i.getY());
    }
    @Override
    public void paint(Graphics g)
    {    
        this.drawAllPiecies();
            
        this.drawActivePoint();
        
        this.drawLocationPoint();
              
        Graphics2D g2d = (Graphics2D) g;
        this.buffer.flush();
        g2d.drawImage(this.buffer,0,0,this);
        
        this.reLoad();
    }
    
    public void drawAllPiecies()
    {
        for(int i = 0 ;  i < 8; i++)
        {
            for(int j = 0 ; j < 8; j++)
            {
                if(this.View[i][j] != null)
                {
                    this.View[i][j].draws(this.bufferGraphic);
                }
            }
        }
    }
    
    public void drawActivePoint()
    {
        if(this.xActive != -1)
        {
            
        
            this.bufferGraphic.setColor(Color.BLUE);
            point getPointActive = this.mapPoint.getFromXY(this.yActive, this.xActive);

            this.bufferGraphic.drawRect((int)getPointActive.getX(),(int) getPointActive.getY(), 37, 37);
            getPointActive = null;
        }
    }
    
    
    public void drawLocationPoint()
    {
        this.bufferGraphic.setColor(Color.RED);  
        point getPointLocation = this.mapPoint.getFromXY(this.yLocation, this.xLocation);
        this.bufferGraphic.drawRect((int)getPointLocation.getX(),(int) getPointLocation.getY(), 37, 37);
        getPointLocation = null;
    }
    
    public void reLoad()
    {
        this.buffer = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
        this.bufferGraphic = (Graphics2D) this.buffer.getGraphics();
        this.bufferGraphic.setStroke(new BasicStroke(2));
    }
    
    @Override
    public void mouseClicked(MouseEvent e) {
        //System.out.printf("\nmouseExited: x:" + e.getX()+", y: "+e.getY());
       //System.out.printf("\nno name:");
        
        //getActivePoint(e.getX(), e.getY());
        
    }

    
    @Override
    public void mousePressed(MouseEvent e) {
        try {
            getActivePoint(e.getX(), e.getY());
        } catch (Exception ex) {
            //Logger.getLogger(perspective.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void mouseExited(MouseEvent e) {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
        @Override
    public void mouseDragged(MouseEvent e) {
        
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        getLocationPoint(e.getX(), e.getY());
        //System.out.printf("\nmouseExited: x:" + e.getX()+", y: "+e.getY());
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
    
    public void getActivePoint(int x, int y) throws Exception
    {
        int xTemp = ((x - 52) / 37);
        int yTemp = ((y - 52) / 37);
        if(x > 52 && x < 348  && y > 52 && y < 348) 
        {        
            if(    this.View[yTemp][xTemp] != null
                && this.View[yTemp][xTemp].getSide() == this.side 
                && (xTemp != this.xActive || this.yActive != yTemp)
              )
            {
                this.xActive = xTemp;
                this.yActive = yTemp;
                this.repaint();
            }
            else if((this.View[yTemp][xTemp] == null || this.View[yTemp][xTemp].getSide() != this.side) && this.xActive != -1)
            {
                point getPointLocation = this.mapPoint.getFromXY(yTemp, xTemp);
                this.View[this.yActive][this.xActive].setDestination(getPointLocation.getX(), getPointLocation.getY());
                this.notMove = false;
                this.currentThread = new Thread(new animationTask(xTemp,yTemp));
                
                this.currentThread.start();
                
                //this.currentThread.join();
                /*synchronized(this.currentThread)
                {
                    this.currentThread.notify();

                }
                this.View[yTemp][xTemp] = this.View[this.yActive][this.xActive];
                this.View[this.yActive][this.xActive] = null;
                this.yActive = -1;
                this.xActive = -1;*/
                //this.currentThread.join();

            }
        }
        else
        {
            this.xActive = -1;
            this.yActive = -1;
            this.repaint();   
        }
    }
    
    public void getLocationPoint(int x, int y)
    {
        int xTemp = ((x - 52) / 37);
        int yTemp = ((y - 52) / 37);
        if(x > 52 && x < 348  && y > 52 && y < 348 && (xTemp != this.xLocation || this.yLocation  != yTemp))
        {
            //System.out.printf("\n"+(x - 52));
            this.xLocation = xTemp;
            this.yLocation = yTemp;
            //System.out.printf("\n"+this.xLocation);
            //System.out.printf("\n"+this.yLocation+"\n");
            //this.active = new point(a,b);
            this.repaint();
        }
    }
    
    class animationTask implements Runnable
    {

        private int x;
        private int y;
        public animationTask(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
        
        @Override
        public void run() {
            boolean isMove = false;
            synchronized(bufferGraphic){
                while(!isMove)
                {
                    /*if(notMove)
                    {
                        synchronized(currentThread)
                        {
                            try {
                                currentThread.wait();
                            } catch (InterruptedException ex) {
                                //Logger.getLogger(perspective.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                    }*/
                    isMove = View[yActive][xActive].move();
                    
                    repaint();
                    
                    try
                    {
                        currentThread.sleep(3);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(perspective.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
            updateData();
            
        }
        
        public void updateData()
        {
            View[this.y][this.x] = View[yActive][xActive];
            
            View[yActive][xActive] = null;
            yActive = -1;
            xActive = -1;
        }

        /**
         * @return the x
         */
        public int getX() {
            return x;
        }

        /**
         * @param x the x to set
         */
        
        public void setX(int x) {
            this.x = x;
        }

        /**
         * @return the y
         */
        
        public int getY() {
            return y;
        }

        /**
         * @param y the y to set
         */
        public void setY(int y) {
            this.y = y;
        }
    }

}
